home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 11 / AMUG BBS in a Box Volume XI (April 1994) (MacWizards).iso / Files / Prog / T / ToolsPlus 2.1.sit / Tools Plus 2.1 ƒ / Tools Plus 2.1 (C & Pascal) / User Manual / 12-System Polling (2 of 4) < prev    next >
Encoding:
Text File  |  1993-10-24  |  25.5 KB  |  383 lines  |  [TEXT/ttxt]

  1. Event Modifiers
  2. ```````````````
  3.   Tools Plus’s event modifier field provides information identical to that obtained directly from the Macintosh’s Event Manager.  To reiterate, the Modifiers field of the event record contains information about the position of the Caps Lock, Shift, Option, Command and Control keys at the time of the event, as well as the position of the mouse button.  This can be used, for example, to detect if the Command key was down when a key was typed (i.e. a Command-key sequence).  In effect, your application could respond to command key sequences that are not menu equivalents by using this method.  Your application could also place special significance on Option-Clicks.  The most common use, however, is Shift-Tab that indicates that the user wants to tab to the previous field.
  4.  
  5.   In the Macintosh’s Event Manager, the Modifiers field of the event record is an integer.  Several of the bits indicate the state of the various modifiers, as detailed in Inside Macintosh Vol 1 and Vol 5.  Tools Plus goes a step further to and automatically decodes individual modifiers in the field.  This is handled through a union in C, and a variant record in Pascal.
  6.  
  7.  
  8.  
  9.  
  10.  
  11. Event Modifiers Using C
  12. ```````````````````````
  13.   When programming in C, Tools Plus’s Modifiers structure is a union that lets you access both the integer obtained from the Macintosh’s Event Manager, as well as the individual flags (bits) within the integer.  Tools Plus’s Modifiers structure looks like this:
  14.  
  15.   union TPModifiersRec {             /*This variable record contains  */
  16.                                      /*  an event's "modifiers" in 2  */
  17.                                      /*  formats…                     */
  18.                                      /*  • Macintosh Event:           */
  19.     int Num;                         /*      integer (bit operations  */
  20.                                      /*      required)                */
  21.                                      /*  • Modifier integer parsed    */
  22.     struct {                         /*    into components:           */
  23.       unsigned int bit15 :1;         /* (reserved bit)                */
  24.       unsigned int bit14 :1;         /* (reserved bit)                */
  25.       unsigned int bit13 :1;         /* (reserved bit)                */
  26.       unsigned int ControlKey :1;    /* Control key was down at event */
  27.       unsigned int OptionKey :1;     /* Option key was down at event  */
  28.       unsigned int CapsLock :1;      /* Caps Lock was down at event   */
  29.       unsigned int ShiftKey :1;      /* Shift key was down at event   */
  30.       unsigned int CmdKey :1;        /* Command key was down at event */
  31.       unsigned int MouseUp :1;       /* Mouse button was UP at event  */
  32.       unsigned int bit6 :1;          /* (reserved bit)                */
  33.       unsigned int bit5 :1;          /* (reserved bit)                */
  34.       unsigned int bit4 :1;          /* (reserved bit)                */
  35.       unsigned int bit3 :1;          /* (reserved bit)                */
  36.       unsigned int bit2 :1;          /* (reserved bit)                */
  37.       unsigned int bit1 :1;          /* (reserved bit)                */
  38.       unsigned int bit0 :1;          /* (reserved bit)                */
  39.     } Bits;                          /*                               */
  40.   };
  41.   typedef union TPModifiersRec TPModifiersRec;
  42.  
  43.  
  44.   Whenever you access any of the individual modifier flags, you reference the “bits” part of the structure.  For example, if you want to check if the Command key was down and the Option key was up when a key was typed, you can use an expression such as this:
  45.  
  46.   if ((Poll.Modifiers.Bits.CmdKey) && (!Poll.Modifiers.Bits.OptionKey))
  47.  
  48.   In contrast, the Modifiers field provided by the Macintosh’s Event Manager requires bitwise “And” operations to determine if a bit is set or not, thereby resulting in source code that looks more cryptic.  The following line duplicates the previous example’s functionality using bitwise “And” operations instead of the available bits:
  49.  
  50.  if ((Poll.Modifiers.Num & cmdKey) && !(Poll.Modifiers.Num & optionKey))
  51.  
  52.   When you are working with the Modifiers structure, you may perform operations exclusively on the integer variant of the structure, on the bits variant, or if you choose, you can mix and match as needed.  Several constants representing the “bit-equivalents” for the various flags contained in the Modifiers integer are available as follows:
  53.  
  54.                             /*Modifier masks                        */
  55.  #define btnState   0x0080  /*set to 1 if mouse button is up        */
  56.  #define cmdKey     0x0100  /*set to 1 if Command key is down       */
  57.  #define shiftKey   0x0200  /*set to 1 if Shift key is down         */
  58.  #define alphaLock  0x0400  /*set to 1 if the Caps Lock key is down */
  59.  #define optionKey  0x0800  /*set to 1 if the option key is down    */
  60.  #define controlKey 0x1000  /*set to 1 if the control key is down   */
  61.  
  62.  
  63.  
  64.  
  65.  
  66. Event Modifiers Using Pascal
  67. ````````````````````````````
  68. When programming in Pascal, Tools Plus’s Modifiers structure is a variant record that lets you access both the integer obtained from the Macintosh’s Event Manager, as well as the individual flags (bits) within the integer.  Tools Plus’s Modifiers record looks like this:
  69.  
  70. {= Polling record's "event modifiers" info}
  71.   TPModifiersRec = packed record       {This variable record contains  }
  72.                                        {  an event's "modifiers" in 2  }
  73.     case integer of                    {  formats…                     }
  74.       0: (                             {  • Macintosh Event:           }
  75.         Num: integer                   {      integer (bit operations  }
  76.       );                               {      required)                }
  77.       1: (                             {  • Modifier integer parsed    }
  78.                                        {    into components:           }
  79.         bit15, bit14, bit13: boolean;  { (reserved bits)               }
  80.         ControlKey: boolean;           { Control key was down at event }
  81.         OptionKey: boolean;            { Option key was down at event  }
  82.         CapsLock: boolean;             { Caps Lock was down at event   }
  83.         ShiftKey: boolean;             { Shift key was down at event   }
  84.         CmdKey: boolean;               { Command key was down at event }
  85.         MouseUp: boolean;              { Mouse button was UP at event  }
  86.         bit6, bit5, bit4, bit3, bit2,  { (reserved bits)               }
  87.         bit1,bit0: boolean;            {                               }
  88.       );                               {                               }
  89.     end;
  90.  
  91.  
  92.   You use each field in the record as an individual modifier variable.  For example, if you want to check if the Command key was down and the Option key was up when a key was typed, you can use an expression such as this:
  93.  
  94.      if Poll.Modifiers.CmdKey and not Poll.Modifiers.OptionKey then
  95.  
  96.   In contrast, the Modifiers field provided by the Macintosh’s Event Manager requires bitwise “And” operations to determine if a bit is set or not, thereby resulting in source code that looks more cryptic.  The following line duplicates the previous example’s functionality using bitwise “And” operations instead of the available bits:
  97.  
  98.     if (BitAnd(Poll.Modifiers.Num,cmdKey) <> 0) and
  99.                       BitAnd(Poll.Modifiers.Num,optionKey) = 0) then
  100.  
  101.   When you are working with the Modifiers record, you may perform operations exclusively on the integer variant of the record, on the bits variant, or if you choose, or you can mix and match as needed.  Several constants representing the “bit-equivalents” for the various flags contained in the Modifiers integer are available as follows:
  102.  
  103. CONST                        {Modifier masks                        }
  104.           btnState  =$0080;  {set to 1 if mouse button is up        }
  105.           cmdKey    =$0100;  {set to 1 if Command key is down       }
  106.           shiftKey  =$0200;  {set to 1 if Shift key is down         }
  107.           alphaLock =$0400;  {set to 1 if the Caps Lock key is down }
  108.           optionKey =$0800;  {set to 1 if the option key is down    }
  109.           controlKey=$1000;  {set to 1 if the control key is down   }
  110.  
  111. ------------------------------------------------------------------------
  112.  
  113. PollSystem
  114. ``````````
  115.   Determine if an event occurred, and obtain that event.  PollSystem also keeps Tools Plus’s automatic processes running.
  116.  
  117.    pascal Boolean PollSystem (TPPollRecord *UserPoll);
  118.  
  119.    function PollSystem(var Poll:TPPollRecord): BOOLEAN;
  120.  
  121. The Poll record contains all the information about an event.
  122.  
  123.   The function’s value will be true if an event was obtained, and false if an event was not obtained.  PollSystem should be called as often as possible (at least sixty times per second) to keep desk accessories, automatic processes, and other applications running under MultiFinder or System 7 running smoothly.
  124.  
  125.   PollSystem calls the Toolbox’s GetNextEvent function which performs all necessary task switching and background processing control.  Desk Accessories’ get their events, and other applications that are also running under MultiFinder or System 7 (or later) get their required processing.  It is important that your application does not do a lot of processing between calls to PollSystem, or it will be a “CPU hog” and make other applications run sluggishly or in spurts and jumps.
  126.  
  127. Warning: Do not call PollSystem from within a BeginUpdateScreen / 
  128.          EndUpdateScreen structure.
  129.  
  130.  
  131.  
  132.  
  133.  
  134. Tools Plus Event Codes
  135. ``````````````````````
  136.   Each event reported by PollSystem is identified by the first field of the polling record, Poll.What.  The Poll.What field contains the event code which tells your application what to do with the event record’s information.  Constants are used to identify event codes as follows:
  137.  
  138.   CONST                   {Tools Plus event codes                 }
  139.     doNothing     =0;     {no event                               }
  140.     doChgWindow   =1;     {user clicked in an inactive window     }
  141.     doRefresh     =2;     {a window has to be refreshed           }
  142.     doGoAway      =3;     {the Go-Away box was clicked            }
  143.     doButton      =4;     {button was clicked                     }
  144.     doMenu        =5;     {menu was selected                      }
  145.     doKeyDown     =6;     {a keyboard key was pressed             }
  146.     doAutoKey     =7;     {a keyboard key is auto-repeating       }
  147.     doKeyUp       =8;     {a keyboard key was released            }
  148.     doClickField  =9;     {mouse clicked in inactive editing field}
  149.     doScrollBar   =10;    {mouse clicked in a scroll bar          }
  150.     doListBox     =11;    {some sort of List Box activity         }
  151.     doClick       =12;    {mouse click/drag [1..3]                }
  152.     doClickControl=101;   {mouse clicked in a custom control      }
  153.     doManualEvent =102;   {manually processed events              }
  154.     doMoveWindow  =103;   {a window was moved by user             }
  155.     doGrowWindow  =104;   {a window was “grown” by user           }
  156.     doClickDesk   =105;   {mouse clicked in the desk top          }
  157.     doZoomWindow  =106;   {zoom box was clicked by user           }
  158.     doSuspend     =107;   {appl. suspended (in background)        }
  159.     doResume      =108;   {appl. resumed (now active appl.)       }
  160.  
  161.   Event codes over 100 will likely be ignored by most applications.  All events are detailed later, telling you how to respond to the event and which fields in the event record contain valid information that is related to the event.
  162.  
  163.  
  164.  
  165.  
  166.  
  167. What Does PollSystem Do?
  168. ````````````````````````
  169.   On the surface, it appears that PollSystem is just a fancy way to get an event from the Toolbox Event Manager.  Quite to the contrary, PollSystem does a lot of work for you.
  170.  
  171.   The biggest service that PollSystem performs is to keep Tools Plus’s automatic processes running smoothly.  To do this, you must understand the difference between an internally processed event, and an externally processed event.
  172.  
  173.  
  174.  
  175.  
  176.  
  177. Internally Processed Events
  178. ```````````````````````````
  179.   An internal event is something that can be processed by Tools Plus without the knowledge or assistance of your application.  Hence the term internal means internal to Tools Plus.  The internal processing of events is how PollSystem drives its automatic tasks.
  180.  
  181.   An example of an internally processed event can be a key-down event from the Toolbox Event Manager.  If the active window belongs to your application and it has an active editing field, the user’s key-strokes will affect the text in the editing field automatically.  Since this event was processed internally, no event is reported to your application.
  182.  
  183.   One of the tricks that PollSystem utilizes, is to process as many internal events as it possibly can before returning to your application.  It will return to your application when the event queue is empty, or when it encounters an event that cannot be processed internally.  Why doesn’t it process just one event at a time?  If your application is busy and the user types 10 characters on the keyboard before PollSystem is called, the single call to PollSystem will process all 10 keystrokes!  This ensures that Tools Plus’s automatic processes occur as smoothly as possible without accumulating a backlog of events.
  184.  
  185.  
  186.  
  187.  
  188.  
  189. Externally Processed Events
  190. ```````````````````````````
  191.   Whenever PollSystem encounters an event it cannot process internally, it reports the event to your application.  An example of this is when the user clicks the close box in the active window.  Your application may want to ask the user if he wants to save the changes before closing the document.  Therefore, PollSystem only reports a request to close a window, and does not actually close it.
  192.  
  193.   Some events may be ignored by your application.  One of these events tells your application that the user dragged a window.  Your application may be interested in a window’s co-ordinates at any given time, in which case this event would be crucial.  In most cases, applications wouldn’t care if the window is dragged, and would always ignore the event.
  194.  
  195.  
  196.  
  197.  
  198.  
  199. Inside PollSystem
  200. `````````````````
  201.   Inside PollSystem describes the inner workings of the PollSystem routine.  Those programmers who are curious about this aspect, or those that want to know how Toolbox Events are translated into Tools Plus events may find this passage interesting.
  202.  
  203.   Every time your application calls PollSystem, several processes are executed as follows:
  204.  
  205.    (1) Tools Plus’s SystemTasks is called to keep desk accessories running and to keep the insertion point flashing in the active editing field, if one is active.
  206.  
  207.    (2) Desk accessories get any events they may require, and task switching occurs to allow other applications running under MultiFinder or System 7 (or later) get some processing time.
  208.  
  209.    (3) The event queue is checked for an event.  If any events exist, the first one is removed from the queue.  If the event can be processed internally, it is and this step is repeated.
  210.  
  211.    (4) If an event is obtained that can not be processed internally, the Tools Plus event record is set up to contain all the required information for the event in a format that is readily usable by your application.
  212.  
  213.    (5) The cursor’s position is checked and its shape is changed if required.
  214.  
  215.    (6) PollSystem returns to your application with an event, or a “no event” (false) status.
  216.  
  217.  
  218.  
  219.  
  220.  
  221. Translating Toolbox events to Tools Plus events
  222. ```````````````````````````````````````````````
  223. Step 3 looks pretty simple when it is summarized in a couple lines, however, the recognition and processing of internal events is quite an extensive duty for Tools Plus.  The table below describes this formidable task by listing the Macintosh’s Toolbox Event Manager’s event, the internal processes that follow, and the event that finally reaches your application.  Remember that some Toolbox events are processed internally and never reach your application, and some events that reach your program can be ignored.
  224.  
  225.  
  226.  
  227. Toolbox’s   | Conditions and                          |  PollSystem’s
  228. Event       | Tools Plus’s Internal Processing        |      Event
  229. ------------+-----------------------------------------+---------------
  230. nullEvent   | none                                    | doNothing
  231. ------------+-----------------------------------------+---------------
  232. mouseDown   | If the watch cursor is displayed then   |
  233.             | the event is ignored (clicks in push    |
  234.             | buttons are optionally exempted)        |
  235.             |-----------------------------------------+---------------
  236.             | Outside of a modal window (beep)        |
  237.             |-----------------------------------------+---------------
  238.             | In an inactive window that belongs to   | doChgWindow
  239.             | your application                        |
  240.             |-----------------------------------------+---------------
  241.             | In an inactive window that belongs to   | doSuspend
  242.             | another application or desk accessory   |
  243.             |-----------------------------------------+---------------
  244.             | Apple menu, except for “About…” item    |
  245.             | (selected item is opened or activated)  |
  246.             |-----------------------------------------+---------------
  247.             | Apple menu’s “About…” item              | doMenu
  248.             |-----------------------------------------+---------------
  249.             | Edit menu’s Undo, Cut, Copy, Paste, or  |
  250.             | Clear item is selected for an active    |
  251.             | editing field or active desk accessory  |
  252.             | (operation is done automatically)       |
  253.             |-----------------------------------------+---------------
  254.             | Other menu selection                    | doMenu
  255.             |-----------------------------------------+---------------
  256.             | In an active desk accessory or other    |
  257.             | application (clicking, dragging, or     |
  258.             | closing, etc.)                          |
  259.             |-----------------------------------------+---------------
  260.             | Selecting or deselecting lines in a     | doListBox
  261.             | list box.                               |
  262.             |-----------------------------------------+---------------
  263.             | Button in the active window (only if    | doButton
  264.             | mouse was released inside the button’s  |
  265.             | area)                                   |
  266.             |-----------------------------------------+---------------
  267.             | Scroll bar in the active window (while  | doScrollBar
  268.             | in up arrow, down arrow, Page up region,|
  269.             | or Page Down region, or if thumb was    |
  270.             | moved)                                  |
  271.             |-----------------------------------------+---------------
  272.             | Active editing field, when setting a    |
  273.             | new insertion point or selection range  |
  274.             | (Edit menu’s items are enabled/disabled |
  275.             | according to the insertion point or     |
  276.             | selection)                              |
  277.             |-----------------------------------------+---------------
  278.             | Inactive editing field                  | doClickField
  279.             |-----------------------------------------+---------------
  280.             | Single-click, double-click, triple-     | doClick
  281.             | click, and/or dragging                  |
  282.             |-----------------------------------------+---------------
  283.             | Active window is dragged by user        | doMoveWindow
  284.             |-----------------------------------------+---------------
  285.             | Active window’s size is changed by      | doGrowWindow
  286.             | using the size box                      |
  287.             |-----------------------------------------+---------------
  288.             | Active window’s close box was clicked   | doGoAway
  289.             |-----------------------------------------+---------------
  290.             | Active window’s “zoom box” was clicked  | doZoomWindow
  291.             |-----------------------------------------+---------------
  292.             | Custom control                          | doClickControl
  293.             |-----------------------------------------+---------------
  294.             | On the desk top                         | doClickDesk
  295. ------------+-----------------------------------------+---------------
  296. mouseUp     | none                                    |
  297. ------------+-----------------------------------------+---------------
  298. keyDown     | If the watch cursor is displayed then   |
  299. autoKey     | the event is ignored (except for        |
  300.             | Command-.)                              |
  301.             |-----------------------------------------+---------------
  302.             | Command key invoking Edit menu’s Undo,  |
  303.             | Cut, Copy, or Paste item in an active   |
  304.             | editing field, or an active desk        |
  305.             | accessory under Finder (the editing     |
  306.             | operation is done automatically)        |
  307.             |-----------------------------------------+---------------
  308.             | Command key invoking a menu             | doMenu
  309.             |-----------------------------------------+---------------
  310.             | Command key NOT invoking a menu         | doKeyDown or
  311.             |                                         | doAutoKey
  312.             |-----------------------------------------+---------------
  313.             | Enter or Return key invoking a default  | doButton
  314.             | push-button                             |
  315.             |-----------------------------------------+---------------
  316.             | Active editing field processing keys    |
  317.             | (Edit menu’s items are enabled/disabled |
  318.             | according to the selection in the       |
  319.             | editing field.  Undo item is changed    |
  320.             | according to field’s contents, such as  |
  321.             | “Undo Typing”)                          |
  322.             |-----------------------------------------+---------------
  323.             | Other key strokes                       | doKeyDown or
  324.             |                                         | doAutoKey
  325. ------------+-----------------------------------------+---------------
  326. keyUp       | If the watch cursor is displayed then   |
  327.             | the event is ignored                    |
  328.             |-----------------------------------------+---------------
  329.             | Active editing field ignores key up     |
  330.             | events                                  |
  331.             |-----------------------------------------+---------------
  332.             | Other key-ups, providing that           | doKeyUp
  333.             | SetEventMask has not masked out key up  |
  334.             | events                                  |
  335. ------------+-----------------------------------------+---------------
  336. updateEvt   | Buttons, scroll bars, custom controls,  | doRefresh
  337.             | editing fields, and list boxes are      |
  338.             | automatically redrawn (refreshed)       |
  339.             | whenever an obscured window is uncovered|
  340. ------------+-----------------------------------------+---------------
  341. activateEvt | When a window is deactivated, the       |
  342.             | following happens automatically:        |
  343.             | [1] text in the active editing field is |
  344.             | deselected and the insertion point is   |
  345.             | removed, [2] list box lines are         |
  346.             | deselected, [3] scroll bars are hidden, |
  347.             | [4] buttons are disabled, and [5] if the|
  348.             | window has a “grow box,” it is hidden.  |
  349.             | When the window is activated again, all |
  350.             | objects return to their normal state.   |
  351. ------------+-----------------------------------------+---------------
  352. diskEvt     | no internal processing                  | doManualEvent
  353. networkEvt  |                                         |
  354. driverEvt   |                                         |
  355. app1Evt     |                                         |
  356. app2Evt     |                                         |
  357. app3Evt     |                                         |
  358. kHighLevel- |                                         |
  359.   Evt       |                                         |
  360. ------------+-----------------------------------------+---------------
  361. app4Evt     | If your application doesn’t respond to  | doManualEvent
  362. osEvt       | Suspend/Resume events, then no internal |
  363.             | processing occurs.                      |
  364.             |-----------------------------------------+---------------
  365.             | If your application responds to Suspend/| doSuspend or
  366.             | Resume events                           | doResume
  367. ----------------------------------------------------------------------
  368.  
  369.  
  370.  
  371. Responding to Events
  372. ````````````````````
  373.   When PollSystem returns with a value of false it indicates that no event has occurred.  This is commonly called a “null event.”  Usually, your application won’t do anything other than idle in the main event loop.  Applications that do on-going processing should do their work only when they receive a null event.
  374.  
  375.   PollSystem returns with a value of true when an event has occurred.  The first field in the polling record is “what,” which tells your application what type of event has occurred.  The following section of this chapter describes how your application should respond to each event.  It also details any programming considerations that should be taken into account when responding to such an event.
  376.  
  377. Note: Your application should call PollSystem as often as possible to
  378.       allow other applications processing time.  If your application
  379.       can’t call PollSystem at least 60 times per second, make up the
  380.       difference with calls to SystemTasks.  Otherwise, periodic
  381.       processes, such as a flashing insertion point or a displayed clock
  382.       will run unevenly, appearing to start and stop.
  383.